﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ITAP.ContourBuilder.Components;

using ITAP.ContourBuilder.GUI;
using System.Drawing;
using ITAP.Core.Modelling;

namespace ITAP.ContourBuilder.Manipulation
{
    public class CommandAddHole : SerializedCommand
    {
        public CommandAddHole(ContourControl control)
            : base(control)
        {
            form = new FormHoleProperties();
        }

        bool idle = false;
        double idleRadius = 10;
        Point mouseMovePoint;
        private FormHoleProperties form;

        ContourHole hole;
        public override void ObtainPeripheryState(GlobalPeripheryState state)
        {
            base.ObtainPeripheryState(state);
            if(state.KeyboardState.KeyMode == KeyMode.Down && state.KeyboardState.KeyState.KeyCode == Keys.Escape)
            {
                hole = null;
                idle = false;
                this.Exit();
            }

            if (state.MouseState.MouseMode == MouseMode.Down && state.MouseState.State.Button == MouseButtons.Left)
            {
                ContourModel rootModel = null;
                IEnumerable<IContourComponent> allComponents = this.control.ContourContainer.GetAllInnerComponents();
                foreach (IContourComponent component in allComponents)
                    if (component is ContourModel)
                    {
                        rootModel = component as ContourModel;
                        break;
                    }

                if (rootModel == null)
                    return;

                idle = false;

                ModelPoint point = this.ScreenPointToModelPoint(state.MouseState.State.Location);
                form.PropertiesChanged += new PropertiesChangedDelegate(form_RadiusChanged);
                
                hole = ContourElementFactory.CreateHole(point, form.Radius);
                form.HolePosition = this.control.ContourContainer.AbsoluteToInner(hole.Position);
                this.control.Invalidate();
                if (form.ShowDialog() == DialogResult.OK)
                {
                    rootModel.AddInnerComponent(hole);
                    this.control.Invalidate();
                }
                else
                {
                    form.PropertiesChanged -= this.form_RadiusChanged;
                    this.Exit();
                    return;
                }
                hole = null;
                form.PropertiesChanged -= this.form_RadiusChanged;
            }
            else if (state.MouseState.MouseMode == MouseMode.Move && state.MouseState.State.Button == MouseButtons.None)
            {
                idle = true;
                mouseMovePoint = state.MouseState.State.Location;
                this.control.Invalidate();
            }
        }

        void form_RadiusChanged()
        {
            idleRadius = form.Radius;
            this.hole.Radius = form.Radius;
            ModelPoint position = this.control.ContourContainer.InnerToAbsolute(form.HolePosition);
            this.hole.MoveTo(position);
            this.control.Invalidate();
        }

        public override void DrawOnGraphics(System.Drawing.Graphics g, int screenWidth, int screenHeight, System.Drawing.RectangleF modelRectangle, ModelPoint cameraCenter, ITAP.Core.Calculations.ModelCoordinateConverter coordinateConverter)
        {
            if (idle)
            {                
                float screenRadius = coordinateConverter.ModelMeasureToScreenMeasure((float)idleRadius, screenWidth, screenHeight, modelRectangle);
                g.DrawEllipse(Pens.DarkGray, mouseMovePoint.X - screenRadius, mouseMovePoint.Y - screenRadius, screenRadius * 2, screenRadius * 2);
            }
            else
            {
                if (hole == null)
                    return;

                RectangleF bbox = hole.BoundingBox;
                RectangleF screenBbox = coordinateConverter.ModelRectangleToScreenRectangle(bbox, screenWidth, screenHeight, modelRectangle, cameraCenter);
                g.DrawEllipse(Pens.DarkGray, Rectangle.Truncate(screenBbox));
            }
        }

        public override string ToString()
        {
            return "Создать отверстия";
        }
    }
}
